package com.example.testapp;

import android.app.AlertDialog;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.text.InputFilter;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.NumberPicker;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;

import com.example.testapp.api.ApiClient;
import com.example.testapp.api.ApiService;
import com.example.testapp.model.BookDataAddRequest;
import com.example.testapp.utils.BaiduOcrHelper;
import com.example.testapp.utils.OcrResultParser;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.Objects;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class AddCardBottomSheetFragment extends BottomSheetDialogFragment {
    private static final String TAG = "AddCardBottomSheet";
    private static final double CARD_HEIGHT = 0.65; // 卡片高度
    private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    private static final int REQUEST_CODE_PICK_IMAGE = 1001; // 相册选择请求码
    private Button btnTime;
    private Button btnExpense;
    private Button btnIncome;
    private Calendar selectedTime;
    private Byte selectedType = 1; // 1:支出, 0:收入
    private EditText editAmount;
    private EditText editCategory;
    private EditText editSource;
    private EditText editRemark;
    private Button btnSave;
    private Button btnCloudAI;
    private Button btnLocalAI;
    private int userId;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 获取传递的userId
        Bundle args = getArguments();
        if (args != null) {
            userId = args.getInt("userId", 0);
            Log.d(TAG, "onCreate: Received userId: " + userId);
        } else {
            Log.w(TAG, "onCreate: No arguments bundle found");
        }
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater,
                             @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.layout_add_card, container, false);
        initViews(view);
        setupInitialState();
        setupClickListeners();
        setupAmountInputFilter();  // 添加金额输入限制
        return view;
    }

    private void initViews(View view) {
        btnTime = view.findViewById(R.id.btnTime);
        btnExpense = view.findViewById(R.id.btnExpense);
        btnIncome = view.findViewById(R.id.btnIncome);
        editAmount = view.findViewById(R.id.editAmount);
        editCategory = view.findViewById(R.id.editCategory);
        editSource = view.findViewById(R.id.editSource);
        editRemark = view.findViewById(R.id.editRemark);
        btnSave = view.findViewById(R.id.btnSave);
        btnCloudAI = view.findViewById(R.id.btnCloudAI);
        btnLocalAI = view.findViewById(R.id.btnLocalAI);
    }

    private void setupInitialState() {
        // 初始时间设定为当前时间
        selectedTime = Calendar.getInstance();
        updateTimeButtonText();

        // 设置默认选中支出
        setTypeSelected(1);
    }

    private void setupClickListeners() {
        // 点击按钮弹出时间选择器
        btnTime.setOnClickListener(v -> {
            Log.d(TAG, "Time button clicked, showing date-time picker");
            showDateTimePicker();
        });

        // 设置收支按钮点击事件
        btnExpense.setOnClickListener(v -> {
            Log.d(TAG, "Expense button clicked, setting type to expense");
            setTypeSelected(1);
        });

        btnIncome.setOnClickListener(v -> {
            Log.d(TAG, "Income button clicked, setting type to income");
            setTypeSelected(0);
        });

        // 云AI识别按钮
        btnCloudAI.setOnClickListener(v -> {
            Toast.makeText(getContext(), "正在打开相册...", Toast.LENGTH_SHORT).show();
            openGalleryForImage();
        });

        // 本地AI识别按钮
        btnLocalAI.setOnClickListener(v -> {
            Toast.makeText(getContext(), "正在进行本地AI识别...", Toast.LENGTH_SHORT).show();
        });

        // 保存按钮
        btnSave.setOnClickListener(v -> {
            saveBookData();
        });
    }

    // 添加金额输入限制
    private void setupAmountInputFilter() {
        editAmount.setFilters(new InputFilter[]{
                // 限制输入格式：数字和最多一个小数点，小数点后最多两位
                new InputFilter() {
                    @Override
                    public CharSequence filter(CharSequence source, int start, int end,
                                               android.text.Spanned dest, int dstart, int dend) {
                        if (source.equals("")) { // 删除操作
                            return null;
                        }
                        String checkString = dest.toString() + source.toString();
                        // 检查是否包含多个小数点
                        if (checkString.contains(".") && checkString.indexOf(".") != checkString.lastIndexOf(".")) {
                            return "";
                        }
                        // 检查小数点后位数
                        if (checkString.contains(".")) {
                            int index = checkString.indexOf(".");
                            if (checkString.length() - index > 3) { // 小数点后最多2位
                                return "";
                            }
                        }
                        // 只允许数字和小数点
                        return source.toString().matches("[0-9.]+") ? null : "";
                    }
                }
        });
    }

    // 保存账单数据
    private void saveBookData() {
        Log.d(TAG, "saveBookData: Attempting to save book data");
        // 获取金额
        String amountStr = editAmount.getText().toString().trim();
        if (TextUtils.isEmpty(amountStr)) {
            Toast.makeText(getContext(), "请输入金额", Toast.LENGTH_SHORT).show();
            return;
        }

        // 验证金额格式
        if (!amountStr.matches("^\\d+(\\.\\d{1,2})?$")) {
            Toast.makeText(getContext(), "金额格式不正确，最多两位小数", Toast.LENGTH_SHORT).show();
            return;
        }

        // 获取类别
        String category = editCategory.getText().toString().trim();
        if (TextUtils.isEmpty(category)) {
            category = "其它";
        }

        // 获取来源
        String source = editSource.getText().toString().trim();
        if (TextUtils.isEmpty(source)) {
            source = "其它";
        }

        // 获取备注
        String remark = editRemark.getText().toString().trim();
        if (TextUtils.isEmpty(remark)) {
            remark = "无备注";
        }

        // 格式化时间
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIME_FORMAT, Locale.getDefault());
        String formattedTime = sdf.format(selectedTime.getTime());

        // 创建请求对象
        BookDataAddRequest request = new BookDataAddRequest();
        request.setUserId(userId);
        request.setType(selectedType);
        request.setPrice(new BigDecimal(amountStr));
        request.setCategory(category); // 默认类别
        request.setSource(source);
        request.setRemark(remark);
        request.setBookDate(formattedTime);

        Log.d(TAG, "saveBookData: BookData request - " +
                "userId=" + userId +
                ", type=" + (selectedType == 1 ? "支出" : "收入") +
                ", amount=" + amountStr +
                ", category=" + category +
                ", source=" + source +
                ", remark=" + remark +
                ", date=" + formattedTime);

        // 调用API保存数据
        ApiService apiService = ApiClient.getClient().create(ApiService.class);
        Call<Void> call = apiService.addBookData(request);
        Log.d(TAG, "saveBookData: Sending API request");

        call.enqueue(new Callback<Void>() {
            @Override
            public void onResponse(Call<Void> call, Response<Void> response) {
                if (response.isSuccessful()) {
                    Log.i(TAG, "saveBookData: Book data saved successfully");
                    Toast.makeText(getContext(), "保存成功", Toast.LENGTH_SHORT).show();

                    // 通知HomeActivity刷新数据
                    if (getActivity() instanceof HomeActivity) {
                        Log.d(TAG, "saveBookData: Notifying HomeActivity to refresh data");
                        ((HomeActivity) getActivity()).refreshData();
                    } else {
                        Log.w(TAG, "saveBookData: Activity is not HomeActivity, cannot refresh");
                    }

                    dismiss(); // 关闭底部弹窗
                } else {
                    try {
                        String errorBody = response.errorBody().string();
                        Log.e(TAG, "saveBookData: Save failed. Code: " + response.code() +
                                ", Message: " + errorBody);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    Toast.makeText(getContext(), "保存失败，请重试", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<Void> call, Throwable t) {
                Log.e(TAG, "saveBookData: Network error: " + t.getMessage(), t);
                Toast.makeText(getContext(), "网络错误: " + t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }

    // 设置选中的类型
    private void setTypeSelected(int type) {
        Log.d(TAG, "setTypeSelected: Setting type to " + (type == 1 ? "支出" : "收入"));
        selectedType = (byte) type;

        if (type == 1) {
            btnExpense.setSelected(true);
            btnIncome.setSelected(false);
            btnExpense.setTextColor(ContextCompat.getColor(requireContext(), android.R.color.black));
            btnIncome.setTextColor(ContextCompat.getColor(requireContext(), R.color.grey_600));
        } else {
            btnExpense.setSelected(false);
            btnIncome.setSelected(true);
            btnExpense.setTextColor(ContextCompat.getColor(requireContext(), R.color.grey_600));
            btnIncome.setTextColor(ContextCompat.getColor(requireContext(), android.R.color.black));
        }
    }

    private void updateTimeButtonText() {
        // 只显示年月日时分
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault());
        String formattedTime = sdf.format(selectedTime.getTime());
        btnTime.setText(formattedTime);
        Log.d(TAG, "updateTimeButtonText: Time updated to " + formattedTime);
    }

    private void showDateTimePicker() {
        View dialogView = LayoutInflater.from(getContext()).inflate(R.layout.datetime_picker_dialog, null);
        AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
        builder.setView(dialogView);
        builder.setTitle("选择时间");

        final NumberPicker yearPicker = dialogView.findViewById(R.id.npYear);
        final NumberPicker monthPicker = dialogView.findViewById(R.id.npMonth);
        final NumberPicker dayPicker = dialogView.findViewById(R.id.npDay);
        final NumberPicker hourPicker = dialogView.findViewById(R.id.npHour);
        final NumberPicker minutePicker = dialogView.findViewById(R.id.npMinute);

        Calendar now = Calendar.getInstance();
        setupNumberPicker(yearPicker, 2000, 2100, now.get(Calendar.YEAR));
        setupNumberPicker(monthPicker, 1, 12, now.get(Calendar.MONTH) + 1);
        setupDayPicker(dayPicker, now);
        setupNumberPicker(hourPicker, 0, 23, now.get(Calendar.HOUR_OF_DAY));
        setupNumberPicker(minutePicker, 0, 59, now.get(Calendar.MINUTE));

        // 监听年月变化来更新“日”的最大值
        NumberPicker.OnValueChangeListener updateDayListener = (picker, oldVal, newVal) -> {
            int year = yearPicker.getValue();
            int month = monthPicker.getValue() - 1; // 注意：Calendar的月份从0开始
            Calendar tempCal = Calendar.getInstance();
            tempCal.set(year, month, 1);
            int maxDay = tempCal.getActualMaximum(Calendar.DAY_OF_MONTH);
            dayPicker.setMaxValue(maxDay);
        };

        yearPicker.setOnValueChangedListener(updateDayListener);
        monthPicker.setOnValueChangedListener(updateDayListener);

        builder.setPositiveButton("确定", (dialog, which) -> {
            selectedTime.set(Calendar.YEAR, yearPicker.getValue());
            selectedTime.set(Calendar.MONTH, monthPicker.getValue() - 1);
            selectedTime.set(Calendar.DAY_OF_MONTH, dayPicker.getValue());
            selectedTime.set(Calendar.HOUR_OF_DAY, hourPicker.getValue());
            selectedTime.set(Calendar.MINUTE, minutePicker.getValue());
            updateTimeButtonText();
        });

        builder.setNegativeButton("取消", null);
        builder.show();
    }

    private void setupNumberPicker(NumberPicker picker, int min, int max, int value) {
        picker.setMinValue(min);
        picker.setMaxValue(max);
        picker.setValue(value);
    }

    private void setupDayPicker(NumberPicker dayPicker, Calendar now) {
        dayPicker.setMinValue(1);
        int maxDay = now.getActualMaximum(Calendar.DAY_OF_MONTH);
        dayPicker.setMaxValue(maxDay);
        dayPicker.setValue(now.get(Calendar.DAY_OF_MONTH));
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        ImageView closeIcon = view.findViewById(R.id.closeIcon);
        closeIcon.setOnClickListener(v -> dismiss());
    }

    @Override
    public void onStart() {
        super.onStart();

        View dialog = Objects.requireNonNull(getDialog()).findViewById(com.google.android.material.R.id.design_bottom_sheet);
        if (dialog != null) {
            ViewGroup.LayoutParams params = dialog.getLayoutParams();
            params.height = (int) (Resources.getSystem().getDisplayMetrics().heightPixels * CARD_HEIGHT);
            dialog.setLayoutParams(params);
        }
    }

    /**
     * 打开系统相册选择图片
     */
    private void openGalleryForImage() {
        Intent intent = new Intent(Intent.ACTION_PICK,
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(intent, REQUEST_CODE_PICK_IMAGE);
        Log.d(TAG, "openGalleryForImage: 打开图库选择图片");
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_PICK_IMAGE && resultCode == getActivity().RESULT_OK && data != null) {
            Uri selectedImageUri = data.getData();
            if (selectedImageUri != null) {
                Log.d(TAG, "onActivityResult: 成功获取图片 URI=" + selectedImageUri);
                Toast.makeText(getContext(), "正在识别图片...", Toast.LENGTH_SHORT).show();
                new ImageProcessingTask().execute(selectedImageUri);
            } else {
                Log.e(TAG, "onActivityResult: 无法获取图片 URI");
            }
        } else {
            Log.w(TAG, "onActivityResult: 用户取消选择图片或选择失败");
        }
    }

    /**
     * 异步任务：处理图片并调用百度OCR
     */
    private class ImageProcessingTask extends AsyncTask<Uri, Void, String> {
        @Override
        protected String doInBackground(Uri... uris) {
            try {
                // 1. 将图片URI转换为Base64字符串
                InputStream inputStream = getActivity().getContentResolver().openInputStream(uris[0]);
                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                String base64Image = BaiduOcrHelper.bitmapToBase64(bitmap);
                Log.i(TAG, "doInBackground: 成功转换为Base64字符串");

                // 2. 调用OCR Helper进行识别
                return BaiduOcrHelper.recognizeText(base64Image);
            } catch (Exception e) {
                Log.e(TAG, "doInBackground: Image processing error: " + e.getMessage(), e);
                return null;
            }
        }

        @Override
        protected void onPostExecute(String result) {
            if (result != null) {
                try {
                    JSONObject json = new JSONObject(result);

                    // 检查是否存在错误
                    if (json.has("error_code")) {
                        int errorCode = json.getInt("error_code");
                        String errorMsg = json.optString("error_msg", "未知错误");
                        Log.e(TAG, "OCR API error: " + errorCode + " - " + errorMsg);
                        Toast.makeText(getContext(), "识别失败: " + errorMsg, Toast.LENGTH_LONG).show();
                        return;
                    }

                    // 检查是否存在识别结果
                    if (json.has("words_result")) {
                        JSONArray wordsResult = json.getJSONArray("words_result");
                        StringBuilder combinedText = new StringBuilder();

                        for (int i = 0; i < wordsResult.length(); i++) {
                            JSONObject item = wordsResult.getJSONObject(i);
                            combinedText.append(item.getString("words")).append("\n");
                        }

                        Log.d(TAG, "onPostExecute: 识别内容：" + combinedText);

                        // 使用工具类解析结果
                        OcrResultParser.ParsedResult parsed = OcrResultParser.parse(combinedText.toString());

                        // 填充解析结果到UI
                        fillParsedData(parsed);

                        Toast.makeText(getContext(), "识别成功，已自动填充", Toast.LENGTH_SHORT).show();
                    } else {
                        Log.w(TAG, "OCR response missing 'words_result' field");
                        Toast.makeText(getContext(), "未识别到有效文字", Toast.LENGTH_SHORT).show();
                    }
                } catch (JSONException e) {
                    Log.e(TAG, "JSON parsing error: " + e.getMessage(), e);
                    Toast.makeText(getContext(), "识别结果解析失败", Toast.LENGTH_SHORT).show();
                }
            } else {
                Toast.makeText(getContext(), "识别失败，请重试", Toast.LENGTH_SHORT).show();
            }
        }
    }

    // 添加填充数据的方法
    private void fillParsedData(OcrResultParser.ParsedResult parsed) {
        // 1. 设置时间
        if (parsed.getDateTime() != null) {
            selectedTime = parsed.getDateTime();
            updateTimeButtonText();
            Log.d(TAG, "设置时间: " + selectedTime.getTime());
        }

        // 2. 设置金额和收支类型
        if (parsed.getAmount() != null) {
            String amount = parsed.getAmount();

            // 检测金额符号设置收支类型
            if (amount.startsWith("-")) {
                setTypeSelected(1); // 支出
                editAmount.setText(amount.substring(1)); // 移除负号
            } else {
                setTypeSelected(0); // 收入
                editAmount.setText(amount);
            }
            Log.d(TAG, "设置金额: " + amount);
        }

        // 3. 设置类别
        if (parsed.getCategory() != null) {
            editCategory.setText(parsed.getCategory());
            Log.d(TAG, "设置类别: " + parsed.getCategory());
        }

        // 4. 设置来源
        if (parsed.getSource() != null) {
            editSource.setText(parsed.getSource());
            Log.d(TAG, "设置来源: " + parsed.getSource());
        }

        // 5. 清空备注
        editRemark.setText("");
        Log.d(TAG, "清空备注字段");
    }
}
